package com.qdlc.p2p.biz.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;

import com.qdlc.p2p.biz.borrowworker.BorrowHelper;
import com.qdlc.p2p.biz.borrowworker.worker.BorrowWorker;
import com.qdlc.p2p.biz.service.ExperienceTenderService;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.dal.dao.*;
import com.qdlc.p2p.dal.dto.*;
import com.qdlc.p2p.dal.model.ExperienceModel;
import com.qdlc.p2p.dal.model.ExperienceTenderModel;
import com.qdlc.p2p.dal.model.interest.EachPlan;
import com.qdlc.p2p.dal.model.interest.InterestCalculator;

@Repository("experienceTenderService")
public class ExperienceTenderServiceImpl implements ExperienceTenderService {

    private Logger logger = Logger.getLogger(ExperienceTenderServiceImpl.class);

    @Resource
    private ExperienceDao experienceDao;

    @Resource
    private ExperienceTenderDao experienceTenderDao;

    @Resource
    private ExperienceCollectionDao experienceCollectionDao;

    @Resource
    private BorrowDao borrowDao;

    @Resource
    private BorrowCollectionDao borrowCollectionDao;

    @Override
    public double sumExperienceCapital(long borrowId, byte status) {
        return experienceTenderDao.sumExperienceCapital(borrowId, status);
    }

    @Override
    public double sumExperienceCapital(long userId, long borrowId, byte status) {
        return experienceTenderDao.sumExperienceCapital(userId, borrowId, status);
    }

    @Override
    public void tenderUseExperience(BorrowTender tender, Object experiences, String accountLogType) {
        if (tender != null && experiences != null) {
            long[] os = (long[]) experiences;
            for (int i = 0; i < os.length; i++) {
                long experienceId = os[i];
                Experience experience = experienceDao.find(experienceId);
                ExperienceModel experienceModel = new ExperienceModel();
                if (experienceModel.validForUse(tender, experience)) {
                    // 保存体验金投标信息
                    ExperienceTender experienceTender = new ExperienceTender();
                    experienceTender.setUser(tender.getUser());
                    experienceTender.setExperience(experience);
                    experienceTender.setBorrow(tender.getBorrow());
                    experienceTender.setTender(tender);
                    experienceTender.setCapital(experience.getAmount());
                    experienceTender.setStatus(ExperienceTenderModel.EXPERIENCE_TENDER_STATUS_PENDING);
                    experienceTender.setAddTime(DateUtil.getNow());
                    experienceTenderDao.save(experienceTender);
                    // 更改体验券状态
                    experience.setStatus(ExperienceModel.EXPERIENCE_STATUS_FREEZE);
                    experience.setUseTime(DateUtil.getNow());
                    experienceDao.update(experience);
                }
            }
        }
    }

    @Override
    public void experienceFullFail(BorrowTender tender, String accountLogType) {
        // 处理experienceTender，修改status
        experienceTenderDao.experienceFullFail(tender.getId());
        // 处理experience，修改staus，延长有效期和过期时间
        List<ExperienceTender> experienceTenderList = experienceTenderDao.findByProperty("tender.id", tender.getId());
        if (experienceTenderList != null && experienceTenderList.size() > 0) {
            for (int i = 0; i < experienceTenderList.size(); i++) {
                ExperienceTender experienceTender = experienceTenderList.get(i);
                Experience experience = experienceTender.getExperience();
                int makeUpDay = DateUtil.daysBetween(experience.getUseTime(), DateUtil.getNow());
                if (makeUpDay > 0) {
                    experience.setValidTime(experience.getValidTime() + makeUpDay);
                    experience.setExpiredTime(DateUtil.rollDay(experience.getExpiredTime(), makeUpDay));
                }
                experience.setStatus(ExperienceModel.EXPERIENCE_STATUS_UNUSED);
                experience.setUseTime(null);
                experienceDao.update(experience);
            }
        }
    }

    @Override
    public void experienceFullSuccess(BorrowTender tender, String accountLogType) {
        List<ExperienceTender> experienceTenderList = experienceTenderDao.findByProperty("tender.id", tender.getId());
        if (experienceTenderList != null && experienceTenderList.size() > 0) {
            for (int i = 0; i < experienceTenderList.size(); i++) {
                ExperienceTender experienceTender = experienceTenderList.get(i);
                // 将体验券置为已使用
                Experience experience = experienceTender.getExperience();
                experience.setStatus(ExperienceModel.EXPERIENCE_STATUS_USED);
                experienceDao.update(experience);

                List<BorrowCollection> collectionList = borrowCollectionDao.findByProperty("tender.id", tender.getId());
                experienceInterest(experienceTender.getExperience(), experienceTender, tender, collectionList);
            }
        }

    }

    /**
     * 生成体验券投标待收collection
     *
     * @param experience
     * @param experienceTender
     * @param tender
     * @param collectionList
     */
    private void experienceInterest(Experience experience, ExperienceTender experienceTender, BorrowTender tender,
                                    List<BorrowCollection> collectionList) {
        double validAccount = experience.getAmount();
        Borrow borrow = borrowDao.find(tender.getBorrow().getId());
        // 从数据库里取出borrow，状态仍然为1，为避免利息计算器flag为false，这里手动设置为3
        if (borrow.getCategory() != 2) {// 排除体验标
            borrow.setStatus(3);
        }
        BorrowWorker worker = BorrowHelper.getWorker(borrow);

        logger.info("体验金投标成功,处理体验券生成待收利息,borrowId:" + borrow.getId() + ",experienceTenderID:" + experienceTender.getId());

        InterestCalculator ic;
        if (borrow.getCategory() == 2) {// 排除体验标
            ic = worker.exInterestCalculator(validAccount, tender.getAddTime());
        } else {
            ic = worker.interestCalculator(validAccount);
        }
        double experienceTotalInterest = BigDecimalUtil.sub(ic.repayTotal(), validAccount);

        List<ExperienceCollection> experienceCollectList = new ArrayList<ExperienceCollection>();
        List<EachPlan> eachPlan = ic.getEachPlanList();

        int i = 0;
        double totalInterest = 0;
        for (int j = 0; j < collectionList.size(); j++) {
            EachPlan plan = eachPlan.get(j);
            BorrowCollection collection = collectionList.get(j);

            ExperienceCollection experienceCollection = new ExperienceCollection();
            experienceCollection.setUser(experienceTender.getUser());
            experienceCollection.setExperience(experience);
            experienceCollection.setExperienceTender(experienceTender);
            experienceCollection.setBorrow(borrow);
            experienceCollection.setCollection(collection);
            experienceCollection.setPeriod((byte) collection.getPeriod());
            experienceCollection.setStatus((byte) 0);
            experienceCollection.setCapital(plan.getCapital());
            experienceCollection.setInterest(plan.getInterest());
            experienceCollection.setAddTime(DateUtil.getNow());
            experienceCollection.setRepaymentTime(collection.getRepaymentTime());

            if (i == eachPlan.size() - 1) { // 最后一期做减法
                double different = BigDecimalUtil.sub(experienceTotalInterest, totalInterest);
                experienceCollection.setInterest(different);
            }
            totalInterest = BigDecimalUtil.add(totalInterest, plan.getInterest());
            experienceCollectList.add(experienceCollection);

            // 保存experienceCollection
            experienceCollectionDao.save(experienceCollectList);
        }
        // 更新experienceTender
        experienceTender.setStatus(ExperienceTenderModel.EXPERIENCE_TENDER_STATUS_SUCCESS);
        experienceTender.setInterest(experienceTotalInterest);
        experienceTenderDao.update(experienceTender);
    }

    @Override
    public void experienceRepay(long borrowId, byte period) {
        if (borrowId > 0 && period >= 0) {
            List<ExperienceCollection> experienceCollectionList = experienceCollectionDao.find(borrowId, period);
            if (experienceCollectionList != null && experienceCollectionList.size() > 0) {
                for (int i = 0; i < experienceCollectionList.size(); i++) {
                    ExperienceCollection collection = experienceCollectionList.get(i);
                    collection.setStatus((byte) 1);
                    collection.setRepaymentYesTime(DateUtil.getNow());
                    experienceCollectionDao.update(collection);
                }
            }
        }
    }

    @Override
    public double getTenderExperienceAmount(long tenderId) {
        return experienceTenderDao.getTenderExperienceAmount(tenderId);
    }

    @Override
    public ExperienceTender getTenderExperience(long tenderId) {
        return experienceTenderDao.getTenderExperience(tenderId);
    }
}
